package com.yenlien.traceyun.plant.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yenlien.traceyun.business.interceptor.UserAuthUtil;
import com.yenlien.traceyun.business.service.rest.usercenter.FileRestService;
import com.yenlien.traceyun.common.utils.Tools;
import com.yenlien.traceyun.plant.dao.*;
import com.yenlien.traceyun.plant.entity.*;
import com.yenlien.traceyun.plant.entity.InputsLog.Type;
import com.yenlien.traceyun.webase.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static com.yenlien.traceyun.plant.utils.Tools.DATE_TIME_FORMATTER;

@Service
public class FarmService {
    @Autowired
    private FarmDao farmDao;
    @Autowired
    private FarmInputsDao farmInputsDao;
    @Autowired
    private InputsDao inputsDao;
    @Autowired
    private InputsLogDao inputsLogDao;
    @Autowired
    private FileRestService fileService;
    @Autowired
    private FarmTypeDao farmTypeDao;

    public Page<Farm> findByList(final Farm farm) {
        Pageable pageable = PageRequest.of(farm.getPage(), farm.getPageSize(), Sort.Direction.DESC, ("createtime"));
        return farmDao.findAll(new Specification<Farm>() {
            private static final long serialVersionUID = -1396496630802017658L;
            @Override
            public Predicate toPredicate(Root<Farm> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Path<String> type = root.get("type");
                Path<String> userName = root.get("userName");
                //构造查询条件
                List<Predicate> list = new ArrayList<Predicate>();
                list.add(cb.equal(type, farm.getType()));
                Predicate[] predicateA = new Predicate[list.size()];
                Predicate predicateAnd = cb.and(list.toArray(predicateA));

                if (StringUtils.isNotEmpty(farm.getJobPersonName())) {
                    List<Predicate> list2 = new ArrayList<>();
                    list2.add(cb.like(userName, "%" + farm.getJobPersonName() + "%"));
                    Predicate[] predicateO = new Predicate[list2.size()];
                    Predicate predicateOr = cb.or(list2.toArray(predicateO));
                    return query.where(predicateAnd, predicateOr).getRestriction();
                } else {
                    return predicateAnd;
                }
            }
        }, pageable);
    }



    public Page<Farm> findByListApp(Farm farm) {
        Pageable pageable = PageRequest.of(farm.getPage(), farm.getPageNum(), Sort.Direction.DESC, ("createtime"));
        return farmDao.findAll(new Specification<Farm>() {
            private static final long serialVersionUID = -1396496630802017658L;
            @Override
            public Predicate toPredicate(Root<Farm> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                //构造查询条件
                List<Predicate> list = new ArrayList<Predicate>();
                if (StringUtils.isNotEmpty(farm.getType())) {
                    list.add(cb.equal(root.get("type"), farm.getType()));
                }
                if (StringUtils.isNotEmpty(farm.getPrincipalName())) {
                    list.add(cb.equal(root.get("principalName"), farm.getPrincipalName()));
                }
                if (StringUtils.isNotEmpty(farm.getPrincipalId())) {
                    list.add(cb.equal(root.get("principalId"), farm.getPrincipalId()));
                }
                if (StringUtils.isNotEmpty(farm.getBatch())) {
                    list.add(cb.equal(root.get("batch"), farm.getBatch()));
                }
                list.add(cb.equal(root.get("finished"), farm.isFinished()));
//                list.add(cb.equal(root.get("status"), "2"));
                // (job_person_id=?2  or (principal_id=?2 and status=1))
//                list.add(cb.equal(root.get("jobPersonId"), UserAuthUtil.getLoginUser().getId()));
                return cb.and(list.toArray(new Predicate[list.size()]));
            }
        }, pageable);
    }

    public Farm findById(String id) {
        Farm farm = farmDao.findById(id);
        if (farm != null) {
            List<FarmInputs> list = farmInputsDao.findByFarmId(id);
            farm.setList(list);
        }
        return farm;
    }


    public JSONObject findTypeList(String companyId) {
        JSONObject object = new JSONObject();
        object.put("typeList", farmDao.findType(companyId).stream().filter(StringUtils::isNotBlank).collect(Collectors.toList()));
        object.put("principalNameList", farmDao.findPrincipalName(companyId).stream().filter(StringUtils::isNotBlank).collect(Collectors.toList()));
        return object;
    }


    /**
     * 用户查看接口
     *
     * @param userType
     * @param
     * @param userId
     * @return
     */
    public List<Farm> lists(String userType, String batch, String userId) {
        String company = "COMPANY";
        if (company.equals(userType)) {
            return farmDao.findJobByPlantId(batch);
        } else {
            return farmDao.findJobDetail(batch, userId);
        }
    }

    /**
     * 完成任务
     */
    public void finish(Farm farm, List<MultipartFile> files) throws Exception {
        Farm pfarm = farmDao.findById(farm.getId());
       // 果园二期注释     其他则放开
//        if (pfarm.getStatus() != 2) {
//            throw new BusinessException("500", "该农事不需要手动完成");
//        }

        if (pfarm.isFinished()) {
            throw new BusinessException("500", "该农事已完成，请不要重复完成");
        }
        farm.setFinished(true);
        fileService.upload(pfarm, farm, files);
        farmDao.save(farm);
        Farm p = farmDao.findById(farm.getPid());
        List<Farm> child = farmDao.findByPid(farm.getPid());
        if (child.size() > 0) {
            int finished = 0;
            for (Farm farm1 : child) {
                if (farm1.isFinished()) {
                    finished++;
                }
            }
            if (p.getJobPersonNames().split(",").length == finished) {
                p.setFinished(true);
                farmDao.save(p);
            }
        }

        List<FarmInputs> list = new ArrayList<>();
        JSONArray array = JSONArray.parseArray(farm.getFarmInputsList());
        if (array != null && array.size() > 0) {
            list = JSONObject.parseArray(array.toJSONString(), FarmInputs.class);
            List<Inputs> inputsList = new ArrayList<>();
            List<InputsLog> logList = new ArrayList<>();
            for (FarmInputs farmInputs : list) {
                farmInputs.setFarmId(farm.getId());
                Inputs inputs = inputsDao.findById(farmInputs.getInputsId());
                inputs.setSurplusNumber(Tools.subtr(inputs.getSurplusNumber(), farmInputs.getUseNumber()));
                inputsList.add(inputs);

                InputsLog log = new InputsLog();
                log.setInputsId(farmInputs.getInputsId());
                log.setNumber(farmInputs.getUseNumber());
                log.setUnits(farmInputs.getUnits());
                log.setType(Type.OUT);
//                log.setTime(farm.getBeginTime());
                log.setTime(LocalDateTime.now().format(DATE_TIME_FORMATTER));
                log.setUsername(UserAuthUtil.getLoginUser().getUsername());
//                String useNum = inputsLogDao.getUseNum(farmInputs.getInputsId());
                log.setSurplusNum(inputs.getSurplusNumber());
                logList.add(log);
            }
            farmInputsDao.saveAll(list);
            inputsDao.saveAll(inputsList);
            inputsLogDao.saveAll(logList);
        }

    }



    @Transactional
    public Farm save(Farm farm, List<MultipartFile> files) throws Exception {
        fileService.upload(null, farm, files);
        return saveFarm(farm);
    }

    public Farm saveFarm(Farm farm) throws Exception {
        if (farm.getStatus() == 0) {
            farm.setJobPersonId(farm.getPrincipalId());
            farm.setJobPersonName(farm.getJobPersonName());
        }
        farm.setLastStep(farm.getPlantId());
        farm.setFinished(false);
        farmDao.save(farm);
        List<FarmInputs> list = new ArrayList<>();
//        JSONArray array = JSONArray.parseArray(farm.getFarmInputsList2());
        JSONArray array = JSONArray.parseArray(farm.getFarmInputsList());
        if (array != null) {
            list = JSONObject.parseArray(array.toJSONString(), FarmInputs.class);
        }

        List<Inputs> inputsList = new ArrayList<>();
        List<InputsLog> logList = new ArrayList<>();
        for (FarmInputs farmInputs : list) {
            farmInputs.setFarmId(farm.getId());
            Inputs inputs = inputsDao.findById(farmInputs.getInputsId());
            inputs.setSurplusNumber(Tools.subtr(inputs.getSurplusNumber(), farmInputs.getUseNumber()));
            inputsList.add(inputs);

            InputsLog log = new InputsLog();
            log.setInputsId(farmInputs.getInputsId());
            log.setNumber(farmInputs.getUseNumber());
            log.setUsername(UserAuthUtil.getLoginUser().getUsername());
            log.setType(Type.OUT);
//            log.setTime(farm.getBeginTime());
            log.setTime(LocalDateTime.now().format(DATE_TIME_FORMATTER));
            log.setSurplusNum(inputs.getSurplusNumber());
            logList.add(log);
        }
        farmInputsDao.saveAll(list);
        inputsDao.saveAll(inputsList);
        inputsLogDao.saveAll(logList);
        return farm;
    }




    @Transactional
    public Farm save2(Farm farm) throws Exception {
        return saveFarm(farm);
    }

    public void push(Farm farm) {
        if (farm.getJobPersonNames().split(",").length <= 0) {
            throw new BusinessException("500", "JobPersonNames 参数错误");
        }
        List<Farm> list = new ArrayList<>();
        Farm renwu = new Farm();
        renwu.setPlantId(farm.getPlantId());
        renwu.setLastStep(farm.getPlantId());
        renwu.setType(farm.getType());
        renwu.setPrincipalId(farm.getPrincipalId());
        renwu.setPrincipalName(farm.getPrincipalName());
        renwu.setBeginTime(farm.getBeginTime());
        renwu.setEndTime(farm.getEndTime());
        renwu.setId(farm.getId());
        renwu.setSoilId(farm.getSoilId());
        renwu.setSoildName(farm.getSoildName());
        renwu.setStatus(1);
        renwu.setWay(farm.getWay());
        renwu.setJobPersonNames(farm.getJobPersonNames());
        farmDao.save(renwu);
        String[] userIds = farm.getUserIds().split(",");
        String[] jobPeronNames = farm.getJobPersonNames().split(",");
        for (int i = 0; i < userIds.length; i++) {
            Farm newFarm = new Farm();
            newFarm.setPlantId(farm.getPlantId());
            newFarm.setType(farm.getType());
            newFarm.setPrincipalId(farm.getPrincipalId());
            newFarm.setPrincipalName(farm.getPrincipalName());
            newFarm.setJobPersonId(userIds[i]);
            newFarm.setJobPersonName(jobPeronNames[i]);
            newFarm.setBeginTime(farm.getBeginTime());
            newFarm.setEndTime(farm.getEndTime());
            newFarm.setPid(renwu.getId());
            newFarm.setSoilId(farm.getSoilId());
            newFarm.setSoildName(farm.getSoildName());
            newFarm.setStatus(2);
            newFarm.setWay(farm.getWay());
            newFarm.setLastStep(farm.getPlantId());
            list.add(newFarm);
        }
        farmDao.saveAll(list);
    }

    public FarmType saveFarmType(FarmType farmType){
        farmType.setState("1");
        String farmTypeId = farmTypeDao.checkByType(farmType.getType());
        if(StringUtils.isNotBlank(farmTypeId)){
//            throw new BusinessException("该类型已存在");
            farmTypeDao.updateState("1", Arrays.asList(farmTypeId));
        }
        return farmTypeDao.save(farmType);
    }

    public List<FarmType> getAllType(String state){
        if(StringUtils.isNotBlank(state))
            return farmTypeDao.getByState(state);
        else
            return farmTypeDao.findAll();
    }

    public List<JSONObject> getAllPrincipalId(){


        return null;
    }

    public void delType(List<String> idList){
        for(String id : idList){
            farmTypeDao.deleteById(id);
        }

//        farmTypeDao.updateState("2", idList);
    }

    public List<Farm> findByUserId(String userId) {
        return farmDao.findByUserId(userId);
    }


    public Object type(String plantId) {
        List<Farm> jobByPlantId = farmDao.findJobByPlantId(plantId);
        return jobByPlantId;
    }

    //
    public int fieldCZCount(String companyId) {
        return farmDao.fieldCZCount(companyId);
    }

}
